<template>
  <v-card style="width:100%;height:90vh">
    <!-- 添加导出按钮 -->
    <v-row dense style="padding:0 20px 0 0;position:absolute;right:0;top:10px;z-index:1">
      <v-col cols="auto" class="d-flex align-center">
        <v-tooltip bottom>
          <template v-slot:activator="{ on, attrs }">
            <v-btn
                    icon
                    color="success"
                    @click="exportExcel"
                    class="mr-2"
                    v-bind="attrs"
                    v-on="on"
                    style="width: 36px; height: 36px"
            >
              <v-icon size="24">mdi-file-excel</v-icon>
            </v-btn>
          </template>
          <span>导出Excel</span>
        </v-tooltip>
        <v-tooltip bottom>
          <template v-slot:activator="{ on, attrs }">
            <v-btn
                    icon
                    color="primary"
                    @click="exportChart"
                    v-bind="attrs"
                    v-on="on"
                    style="width: 36px; height: 36px"
            >
              <v-icon size="24">mdi-image</v-icon>
            </v-btn>
          </template>
          <span>导出图片</span>
        </v-tooltip>
      </v-col>
    </v-row>
    <v-row style="padding-left:20px;margin-bottom:-25px">
      <v-col cols="2">
        <v-select class="ma-1" dense :items="types" @change="loadFrrData()" label="类型" v-model="lamp_type"></v-select>
      </v-col>
      <v-col cols="2">
        <v-select class="ma-1" dense :items="bases" @change="loadFrrData()" label="基地" v-model="base"></v-select>
      </v-col>
      <v-col cols="2">
        <VZDatePicker v-model="baseMonth" label="灯具制造日期结束月份" type="month" ></VZDatePicker>
      </v-col>
      <v-col  cols="2">
        <v-combobox dense v-model="mainPlant" :items="mainPlantItems" @change="loadFrrData()" label="主机厂" clearable ></v-combobox>
      </v-col>
      <v-col cols="2">
        <v-select class="ma-1" dense :items="pieTypeItems" @change="loadDefectData()" label="缺陷统计类型" v-model="pieType"></v-select>
      </v-col>
      <v-col cols="1">
        <v-tooltip bottom style="position:relative;top:2px;right:2px">
          <template v-slot:activator="{ on, attrs }">
            <v-icon
                    color="primary"
                    dark
                    v-bind="attrs"
                    v-on="on"
            >
              mdi-help-rhombus
            </v-icon>
          </template>
          <h4>当前页面说明：</h4>
          <p>1、当前页面统计的所有月份或者日期都是MQP售后数据的【灯具制造日期】。</p>
          <p>2、3MIS 不良率 = 当月退回灯具总数（（返修日期-灯具制造日期）≤90天的灯具总数）/当月发货总数</p>
          <p>3、点击左侧缺陷统计类型可使右下角的饼图按照不同的维度统计缺陷分布。</p>
        </v-tooltip>
      </v-col>
    </v-row>
    <v-row>
      <div ref="frrTarget" style="width:100%;height:32vh"></div>
    </v-row>
                <v-row style="height:46vh">
        <v-col cols="7" style="padding-right:3px" v-show="currentMis && clickMonth">
          <div style="height:23vh">
            <div ref="frrTop20RateTarget" style="width:100%;height:100%"></div>
          </div>
          <div style="height:23vh">
            <div ref="frrTop20NumTarget" style="width:100%;height:100%"></div>
          </div>
        </v-col>
        <v-col cols="5" style="padding-left:3px" v-show="true">
          <div ref="defectLineTarget" style="width:100%;height:46vh"></div>
        </v-col>
      </v-row>
  </v-card>
</template>
<script>
  export default {
    data () {
      return {
        lamp_type:'FRONT_LAMP',
        base: '',
        frr_top_sql:"SELECT DATE_FORMAT(a.MADE_TIME, '%Y-%m') as month,COUNT(CASE WHEN DATEDIFF(a.REPAIR_TIME, a.MADE_TIME) BETWEEN 0 AND 93 THEN 1 END) AS mis3,COUNT(CASE WHEN DATEDIFF(a.REPAIR_TIME, a.MADE_TIME) BETWEEN 0 AND 186 THEN 1 END) AS mis6,COUNT(CASE WHEN DATEDIFF(a.REPAIR_TIME, a.MADE_TIME) BETWEEN 0 AND 279 THEN 1 END) AS mis9,COUNT(CASE WHEN DATEDIFF(a.REPAIR_TIME, a.MADE_TIME) BETWEEN 0 AND 365 THEN 1 END) AS mis12,COUNT(CASE WHEN DATEDIFF(a.REPAIR_TIME, a.MADE_TIME) BETWEEN 0 AND 730 THEN 1 END) AS mis24,COUNT(CASE WHEN DATEDIFF(a.REPAIR_TIME, a.MADE_TIME) BETWEEN 0 AND 1095 THEN 1 END) AS mis36,COUNT(*) AS total_count FROM (SELECT a.id,a.MADE_TIME,a.REPAIR_TIME,p.ASSEMBLY_CODE FROM tt_sale_record_qms a LEFT JOIN TB_STANDARD_ASSEMBLY_PRODUCT p ON a.material_id = p.id LEFT JOIN TB_STANDARD_ASSEMBLY_PRODUCT_REFERRED r ON p.REFERRED_ID = r.id WHERE a.MARK_FOR_DELETE = 0 AND a.material_id IS NOT NULL AND a.MADE_TIME IS NOT NULL AND a.REPAIR_TIME IS NOT NULL AND p.MARK_FOR_DELETE = 0 AND p.REFERRED_ID IS NOT NULL AND r.MARK_FOR_DELETE = 0 AND r.lamp_type = #{lamp_type} [AND a.BASE = #{base}] [AND a.customer_id = #{customer_id}] and a.MADE_TIME >= #{startDate} AND a.MADE_TIME <= #{endDate} AND DATEDIFF(a.REPAIR_TIME, a.MADE_TIME) BETWEEN 0 AND 1095)a group by DATE_FORMAT(a.MADE_TIME, '%Y-%m')",
        frr_bottom_sql:"SELECT DATE_FORMAT(a.YEAR_MONTHS, '%Y-%m') as month,SUM(a.SHIPPED_QTY) AS num FROM tb_part_sendout a LEFT JOIN tb_standard_assembly_product b ON a.matnr = b.ASSEMBLY_CODE left join tb_standard_assembly_product_referred r on b.REFERRED_ID = r.id WHERE a.YEAR_MONTHS >= #{startDate} AND a.YEAR_MONTHS <= #{endDate} and b.MARK_FOR_DELETE = 0 and r.LAMP_TYPE = #{lamp_type} GROUP BY DATE_FORMAT(a.YEAR_MONTHS, '%Y-%m')",
        frr_top20_top_sql:"select * from (SELECT r.SIMPLE_CALL,count(1) as num FROM tt_sale_record_qms a LEFT JOIN TB_STANDARD_ASSEMBLY_PRODUCT p ON a.material_id = p.id LEFT JOIN TB_STANDARD_ASSEMBLY_PRODUCT_REFERRED r ON p.REFERRED_ID = r.id WHERE a.MARK_FOR_DELETE = 0 AND a.material_id IS NOT NULL AND a.MADE_TIME IS NOT NULL AND a.REPAIR_TIME IS NOT NULL AND p.MARK_FOR_DELETE = 0 AND p.REFERRED_ID IS NOT NULL AND r.MARK_FOR_DELETE = 0 AND r.lamp_type = #{lamp_type} [AND a.BASE = #{base}] [AND a.customer_id = #{customer_id}] and DATE_FORMAT(a.MADE_TIME, '%Y-%m') = #{month} AND DATEDIFF(a.REPAIR_TIME, a.MADE_TIME) BETWEEN #{misStart} AND #{misEnd} group by r.SIMPLE_CALL) a order by a.num desc",
        frr_top20_bottom_sql:"SELECT r.SIMPLE_CALL,SUM(a.SHIPPED_QTY) AS num FROM tb_part_sendout a LEFT JOIN tb_standard_assembly_product b ON a.matnr = b.ASSEMBLY_CODE left join tb_standard_assembly_product_referred r on b.REFERRED_ID = r.id WHERE a.YEAR_MONTHS >= #{startDate} AND a.YEAR_MONTHS <= #{endDate} and b.MARK_FOR_DELETE = 0 and r.LAMP_TYPE = #{lamp_type} GROUP BY r.SIMPLE_CALL",
        defect_pie_sql:"SELECT ifnull(d.FIRST_ANALYSE,'无') as name,count(a.id) as value FROM tt_sale_record_qms a LEFT JOIN TB_STANDARD_ASSEMBLY_PRODUCT p ON a.material_id = p.id left join TT_MQP_DEFECT d on a.defect_id = d.id WHERE a.MARK_FOR_DELETE = 0 AND a.material_id IS NOT NULL AND a.MADE_TIME IS NOT NULL AND a.REPAIR_TIME IS NOT NULL AND p.MARK_FOR_DELETE = 0 [AND p.referred_simple_call = #{referred_simple_call}] [and DATE_FORMAT(a.MADE_TIME, '%Y-%m') = #{month}] [AND a.BASE = #{base}] [AND a.customer_id = #{customer_id}] AND DATEDIFF(a.REPAIR_TIME, a.MADE_TIME) BETWEEN #{misStart} AND #{misEnd}  group by d.FIRST_ANALYSE",
        describe_pie_sql:"SELECT ifnull(a.consumer_describe_extract,'无') as name,count(a.id) as value FROM tt_sale_record_qms a LEFT JOIN TB_STANDARD_ASSEMBLY_PRODUCT p ON a.material_id = p.id  WHERE a.MARK_FOR_DELETE = 0 AND a.material_id IS NOT NULL AND a.MADE_TIME IS NOT NULL AND a.REPAIR_TIME IS NOT NULL AND p.MARK_FOR_DELETE = 0 [AND p.referred_simple_call = #{referred_simple_call}] [and DATE_FORMAT(a.MADE_TIME, '%Y-%m') = #{month}] [AND a.BASE = #{base}] [AND a.customer_id = #{customer_id}] AND DATEDIFF(a.REPAIR_TIME, a.MADE_TIME) BETWEEN #{misStart} AND #{misEnd}  group by a.consumer_describe_extract",
        types:[],
        bases:[],
        mainPlantItems:[],
        frrTopList:[],
        frrBottomList:[],
        baseMonth:this.getThreeMonthsAgoMonth(),
        clickMonth:'',//当前点击的frr综合的月份
        currentMis:'',//当前点击的frr综合的MIS
        frrTop20TopData:[],
        frrTop20BottomData:[],
        fixNum:4,//保留小数位
        referred_simple_call:'',//当前点击的不良率top20简称
        rateName:'千分比',
        rateNum:1000,
        rateSymbol:'‰',
        mainPlant:'',
        pieTypeItems:[{text:'用户简述',value:'DESCRIBE'},{text:'初步分析结果',value:'DEFECT'}],
        pieType:'DESCRIBE',
        firstLoad: true,
      }
    },
    computed: {
      pie_sql:function () {
        return this.pieType == 'DESCRIBE' ? this.describe_pie_sql : this.defect_pie_sql;
      },
      mainPlantId:function () {
        return this.mainPlant ? this.mainPlant.value : '';
      },
      mainPlantName:function () {
        return this.mainPlant ? this.mainPlant.text : '';
      },
      lamp_type_show: function () {
        return app.utils.getEntryValue("LAMP_TYPE", this.lamp_type);
      },
      base_show: function () {
        return app.utils.getEntryValue("MQP_BASE", this.base);
      },
      misQueryData:function () {
        if(this.currentMis == '3MIS'){
          return [0,93];
        }else if(this.currentMis == '6MIS'){
          return [0,186];
        }else if(this.currentMis == '9MIS'){
          return [0,279];
        }else if(this.currentMis == '12MIS'){
          return [0,365];
        }else if(this.currentMis == '24MIS'){
          return [0,730];
        }else if(this.currentMis == '36MIS'){
          return [0,1095];
        }else{
          return [0,0];
        }
      },
      clickDateRange:function(){
        if(!this.clickMonth){
          return [];
        }
        // 解析输入的年月
        const [year, month] = this.clickMonth.split('-').map(Number);
        // 月份的第一天（注意：JavaScript 的月份是 0-11）
        const startDate = new Date(year, month - 1, 1);
        // 下个月的第 0 天就是当前月的最后一天
        const endDate = new Date(year, month, 0);
        // 格式化为 "YYYY-MM-DD"
        const format = (date) => {
          const y = date.getFullYear();
          const m = String(date.getMonth() + 1).padStart(2, '0');
          const d = String(date.getDate()).padStart(2, '0');
          return `${y}-${m}-${d}`;
        };
        return [format(startDate),format(endDate)]
      },

      start_end_data: function () {
        const [yearStr, monthStr] = this.baseMonth.split('-');
        const currentYear = parseInt(yearStr, 10);
        const currentMonth = parseInt(monthStr, 10);
        // 计算3年前的日期
        const threeYearsAgoYear = currentYear - 3;
        // 获取当前月份的第一天
        const startDate = `${threeYearsAgoYear}-${String(currentMonth).padStart(2, '0')}-01`;
        // 获取当前月份的最后一天
        const lastDay = new Date(currentYear, currentMonth, 0).getDate();
        const endDate = `${currentYear}-${String(currentMonth).padStart(2, '0')}-${String(lastDay).padStart(2, '0')}`;
        return [startDate, endDate];
      },
      month_list:function(){
        // 解析传入的基准月份
        const [yearStr, monthStr] = this.baseMonth.split('-');
        const baseYear = parseInt(yearStr, 10);
        const baseMonthNum = parseInt(monthStr, 10);

        const months = [];

        // 生成近3年（36个月）的所有月份
        for (let i = 35; i >= 0; i--) {
          const date = new Date(baseYear, baseMonthNum - 1 - i, 1);
          const year = date.getFullYear();
          const month = date.getMonth() + 1;
          months.push(`${year}-${String(month).padStart(2, '0')}`);
        }
        return months;
      }
    },
    watch: {
      baseMonth(newValue, oldValue) {
        if (newValue != undefined && newValue != '') {
          this.loadFrrData();
        }
      },
    },
    methods: {
      getCurrentMonth() {
        const currentDate = new Date();
        const year = currentDate.getFullYear();
        const month = String(currentDate.getMonth() + 1).padStart(2, '0'); // 月份补零
        return `${year}-${month}`;
      },
      getThreeMonthsAgoMonth() {
        const currentDate = new Date();
        currentDate.setMonth(currentDate.getMonth() - 3);
        const year = currentDate.getFullYear();
        const month = String(currentDate.getMonth() + 1).padStart(2, '0');
        return `${year}-${month}`;
      },
      loadTypes(){
        let data = [];
        app.utils.getEntrys('LAMP_TYPE').forEach(item => {
          data.push({
            text: item.name,
            value: item.code
          });
        })
        this.types = data
      },
      loadBases(){
        let data = [{text: '全部', value: ''}];
        app.utils.getEntrys('MQP_BASE').forEach(item => {
          data.push({
            text: item.name,
            value: item.code
          });
        })
        this.bases = data;
      },
      loadMainPlant(){
        let _this = this;
        _this.mainPlantItems = [];
        app.utils.ajaxRequest({
          hideMsg: true,
          hideMask: true,
          url: app.path().dispose + "?functionCode=QMS_MAIN_ENGINE_PLANT_SELECT",
          params: {is_queryPage: false},
          callBack(res) {
            if (res.success && res.rows.length > 0) {
              let dataList = res.rows;
              let plantList = [];
              dataList.forEach((item) => {
                let map = {};
                map.text = item.main_engine_plant_name;
                map.value = item.id;
                plantList.push(map);
              })
              _this.mainPlantItems = plantList;
            }
          },
        })
      },
      loadFrrTopData(callback) {
        let _this = this;
        let params = {"SQL": this.frr_top_sql};
        app.utils.ajaxRequest({
          hideMsg: true,
          hideMask: true,
          url: app.path().dispose + "?functionCode=QMS_CUSTOM_QUERY_SQL",
          params: {
            "queryCondition[lamp_type]": _this.lamp_type,
            "queryCondition[base]": _this.base,
            "queryCondition[customer_id]": _this.mainPlantId,
            "queryCondition[startDate]": _this.start_end_data[0],
            "queryCondition[endDate]": _this.start_end_data[1],
            functionParam: JSON.stringify(params)
          },
          callBack(res) {
            _this.frrTopList = [];
            if (res.success) {
              _this.frrTopList = res.rows;
              if (callback) callback();
            }
          }
        });
      },
      loadFrrBottomData(callback) {
        let _this = this;
        let params = {"SQL": this.frr_bottom_sql};
        app.utils.ajaxRequest({
          hideMsg: true,
          hideMask: true,
          url: app.path().dispose + "?functionCode=QMS_CUSTOM_QUERY_SQL",
          params: {
            "queryCondition[lamp_type]": _this.lamp_type,
            "queryCondition[startDate]": _this.start_end_data[0],
            "queryCondition[endDate]": _this.start_end_data[1],
            functionParam: JSON.stringify(params)
          },
          callBack(res) {
            _this.frrBottomList = [];
            if (res.success) {
              _this.frrBottomList = res.rows;
              if (callback) callback();
            }
          }
        });
      },
      loadFrrData(){
        let _this = this;

        this.referred_simple_call = '';
        this.clickMonth = '';
        this.currentMis = '';

        // 将两个请求封装为Promise
        const frrTopPromise = new Promise((resolve) => {
          _this.loadFrrTopData(resolve);
        });

        const frrBottomPromise = new Promise((resolve) => {
          _this.loadFrrBottomData(resolve);
        });

        // 等待两个Promise都完成
        Promise.all([frrTopPromise, frrBottomPromise]).then((results) => {
          _this.loadFrrChart();
          // 首次加载或条件变化时，自动加载下方柱状图（3MIS+当前月份-3月或已选月份）
          _this.currentMis = '3MIS';
          _this.clickMonth = _this.baseMonth;
          _this.clickFrr();
          if (_this.firstLoad) {
            _this.firstLoad = false;
          }
          
          // 添加日志，显示加载的数据量
          console.log("数据加载完成 - frrTopList:", _this.frrTopList.length, "条记录");
          console.log("数据加载完成 - frrBottomList:", _this.frrBottomList.length, "条记录");
        });

      },
      loadFrrChart(){
        let _this = this;
        this.chartFrrTarget = this.frrTarget || this.$echarts.init(this.$refs.frrTarget);
        let data3 = [];
        let data6 = [];
        let data9 = [];
        let data12 = [];
        let data24 = [];
        let data36 = [];
        let dataList = [];
        _this.month_list.forEach((item)=>{
          let topData = _this.frrTopList.find(topItem => topItem.month === item);
          let bottomData = _this.frrBottomList.find(bottomItem => bottomItem.month === item);
          if(topData == undefined || bottomData == undefined){
            dataList.push(0);
            data3.push(0);
            data6.push(0);
            data9.push(0);
            data12.push(0);
            data24.push(0);
            data36.push(0);
          }else{
            data3.push((topData.mis3*this.rateNum/bottomData.num).toFixed(this.fixNum));
            data6.push((topData.mis6*this.rateNum/bottomData.num).toFixed(this.fixNum));
            data9.push((topData.mis9*this.rateNum/bottomData.num).toFixed(this.fixNum));
            data12.push((topData.mis12*this.rateNum/bottomData.num).toFixed(this.fixNum));
            data24.push((topData.mis24*this.rateNum/bottomData.num).toFixed(this.fixNum));
            data36.push((topData.mis36*this.rateNum/bottomData.num).toFixed(this.fixNum));
          }
        })

        let option = {
          color: ['#D32F2F', '#800080', '#FB8C00', '#FBC02D', '#1976D2', '#388E3C'],
          title: {
            text: '【'+this.lamp_type_show+'】'+(this.base ? '【'+this.base_show+'】' : '')+(this.mainPlantName ? '【'+this.mainPlantName+'】' : '')+'华视市场不良率总合',
            left: '2%',
            textStyle: {
              fontSize: 16
            }
          },
          legend: {
            data: ['3MIS', '6MIS', '9MIS', '12MIS', '24MIS','36MIS'],
            selector: [
              {
                type: 'all',
                title: '全选'
              },
              {
                type: 'inverse',
                title: '全不选'
              }
            ],
            selected: {
              '3MIS': true,
              '6MIS': false,
              '9MIS': false,
              '12MIS': false,
              '24MIS': false,
              '36MIS': false,
            },
            right:'2%'
          },
          tooltip: {
            trigger: 'axis',
            axisPointer: {
              type: 'shadow'
            },
            formatter: function(params) {
              let str = params[0].name + '<br/>';
              params.forEach(item => {
                str += item.marker + item.seriesName + ': ' + item.value + _this.rateSymbol + '<br/>';
              });
              return str;
            }
          },
          grid: {
            left: '3%',
            right: '4%',
            bottom: '8%',
            containLabel: true
          },
          xAxis: {
            type: 'category',
            boundaryGap: false,
            data: _this.month_list,
            axisLabel: {
              z: 10,
              margin: 10
            }
          },
          yAxis: {
            type: 'value',
            name: this.rateName,
            axisLabel: {
              formatter: '{value}'+this.rateSymbol
            }
          },
          dataZoom: [
            {
              show: true,
              realtime: true,
              start: 65,
              end: 100,
              height: 15,
              bottom: 0,
              backgroundColor: 'rgba(47, 69, 84, 0.15)',
              dataBackground: {
                lineStyle: {
                  opacity: 0.4
                },
                areaStyle: {
                  opacity: 0.15
                }
              },
              fillerColor: 'rgba(167,183,204,0.15)',
              borderColor: 'rgba(167,183,204,0.3)',
              handleIcon: 'path://M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
              handleSize: '70%',
              handleStyle: {
                color: '#fff',
                shadowBlur: 3,
                shadowColor: 'rgba(0, 0, 0, 0.3)',
                shadowOffsetX: 2,
                shadowOffsetY: 2
              },
              textStyle: {
                color: 'transparent'
              },
              z: 2
            },
            {
              type: 'inside',
              realtime: true,
              start: 65,
              end: 100,
              zoomOnMouseWheel: true,
              moveOnMouseMove: true,
              xAxisIndex: [0, 1]
            }
          ],
          series: [
            {
              data: data36,
              type: 'line',
              name:'36MIS',
              symbolSize:8,
              smooth: true,
              z: 1,
              itemStyle: {
                normal: {
                  label: {
                    show: false  // 隐藏数值标签
                  },
                }
              },
            },
            {
              data: data24,
              type: 'line',
              name:'24MIS',
              symbolSize:8,
              smooth: true,
              z: 2,
              itemStyle: {
                normal: {
                  label: {
                    show: false  // 隐藏数值标签
                  },
                }
              },
            },
            {
              data: data12,
              type: 'line',
              name:'12MIS',
              symbolSize:8,
              smooth: true,
              z: 3,
              itemStyle: {
                normal: {
                  label: {
                    show: false  // 隐藏数值标签
                  },
                }
              },
            },
            {
              data: data9,
              type: 'line',
              name:'9MIS',
              symbolSize:8,
              smooth: true,
              z: 4,
              itemStyle: {
                normal: {
                  label: {
                    show: false  // 隐藏数值标签
                  },
                }
              },
            },
            {
              data: data6,
              type: 'line',
              name:'6MIS',
              symbolSize:8,
              smooth: true,
              z: 5,
              itemStyle: {
                normal: {
                  label: {
                    show: false  // 隐藏数值标签
                  },
                }
              },
            },
            {
              data: data3,
              type: 'line',
              name:'3MIS',
              symbolSize:8,
              smooth: true,
              z: 6,
              itemStyle: {
                normal: {
                  label: {
                    show: false  // 隐藏数值标签
                  },
                }
              },
            }
          ]
        }
        option && this.chartFrrTarget.setOption(option);
        this.chartFrrTarget.off('click');
        this.chartFrrTarget.on('click', function (params) {
          _this.clickMonth = params.name;
          _this.currentMis = params.seriesName;
          _this.referred_simple_call = '';
          console.log(params)
          console.log(_this.currentMis);
          console.log(_this.misQueryData);
          _this.clickFrr();

        });
      },
      clickFrr(){
        let _this = this;
        // 将两个请求封装为Promise
        const frrTopPromise = new Promise((resolve) => {
          _this.loadClickFrrTop(resolve);
        });

        const frrBottomPromise = new Promise((resolve) => {
          _this.loadClickFrrBottom(resolve);
        });

        // 等待两个Promise都完成
        Promise.all([frrTopPromise, frrBottomPromise]).then((results) => {

          _this.loadClickFrrChart();
        });
      },
      loadClickFrrTop(callback) {
        let _this = this;
        let params = {"SQL": this.frr_top20_top_sql};
        app.utils.ajaxRequest({
          hideMsg: true,
          hideMask: true,
          url: app.path().dispose + "?functionCode=QMS_CUSTOM_QUERY_SQL",
          params: {
            "queryCondition[lamp_type]": _this.lamp_type,
            "queryCondition[base]": _this.base,
            "queryCondition[customer_id]": _this.mainPlantId,
            "queryCondition[month]": _this.clickMonth,
            "queryCondition[misStart]": _this.misQueryData[0],
            "queryCondition[misEnd]": _this.misQueryData[1],
            functionParam: JSON.stringify(params)
          },
          callBack(res) {
            _this.frrBottomList = [];
            if (res.success) {
              _this.frrTop20TopData = res.rows;
              if (callback) callback();
            }
          }
        });
      },
      loadClickFrrBottom(callback) {
        let _this = this;
        let params = {"SQL": this.frr_top20_bottom_sql};
        app.utils.ajaxRequest({
          hideMsg: true,
          hideMask: true,
          url: app.path().dispose + "?functionCode=QMS_CUSTOM_QUERY_SQL",
          params: {
            "queryCondition[lamp_type]": _this.lamp_type,
            "queryCondition[startDate]": _this.clickDateRange[0],
            "queryCondition[endDate]": _this.clickDateRange[1],
            functionParam: JSON.stringify(params)
          },
          callBack(res) {
            _this.frrBottomList = [];
            if (res.success) {
              _this.frrTop20BottomData = res.rows;
              if (callback) callback();
            }
          }
        });
      },
      // 获取全部产品的平均不良率
      loadTotalAverage(callback) {
        let _this = this;
        // 根据当前选择的MIS获取日期范围
        const misStart = this.misQueryData[0];
        const misEnd = this.misQueryData[1];

        // 使用相同的条件查询分子(返修总数)和分母(发货总数)
        let params1 = {"SQL": `SELECT COUNT(CASE WHEN DATEDIFF(a.REPAIR_TIME, a.MADE_TIME) BETWEEN ${misStart} AND ${misEnd} THEN 1 END) AS total_return FROM tt_sale_record_qms a LEFT JOIN TB_STANDARD_ASSEMBLY_PRODUCT p ON a.material_id = p.id LEFT JOIN TB_STANDARD_ASSEMBLY_PRODUCT_REFERRED r ON p.REFERRED_ID = r.id WHERE a.MARK_FOR_DELETE = 0 AND a.material_id IS NOT NULL AND a.MADE_TIME IS NOT NULL AND a.REPAIR_TIME IS NOT NULL AND p.MARK_FOR_DELETE = 0 AND p.REFERRED_ID IS NOT NULL AND r.MARK_FOR_DELETE = 0 `};

        app.utils.ajaxRequest({
          hideMsg: true,
          hideMask: true,
          url: app.path().dispose + "?functionCode=QMS_CUSTOM_QUERY_SQL",
          params: {
            functionParam: JSON.stringify(params1)
          },
          callBack(res) {
            if (res.success && res.rows.length > 0) {
              const totalReturn = res.rows[0].total_return;

              // 获取同条件下的发货总数
              let params2 = {"SQL": `SELECT SUM(a.SHIPPED_QTY) AS total_shipped FROM tb_part_sendout a LEFT JOIN tb_standard_assembly_product b ON a.matnr = b.ASSEMBLY_CODE left join tb_standard_assembly_product_referred r on b.REFERRED_ID = r.id WHERE  b.MARK_FOR_DELETE = 0 `};

              app.utils.ajaxRequest({
                hideMsg: true,
                hideMask: true,
                url: app.path().dispose + "?functionCode=QMS_CUSTOM_QUERY_SQL",
                params: {
                  functionParam: JSON.stringify(params2)
                },
                callBack(shipRes) {
                  if (shipRes.success && shipRes.rows.length > 0 && shipRes.rows[0].total_shipped > 0) {
                    const totalShipped = shipRes.rows[0].total_shipped;
                    const totalAverage = (totalReturn * _this.rateNum / totalShipped).toFixed(_this.fixNum);
                    if (callback) callback(totalAverage);
                  } else {
                    if (callback) callback(0);
                  }
                }
              });
            } else {
              if (callback) callback(0);
            }
          }
        });
      },

      loadClickFrrChart(){
        console.log("frrTop20BottomData",this.frrTop20BottomData);
        let _this = this;
        const bottomDataList = this.frrTop20BottomData.filter(item1 =>
                this.frrTop20TopData.some(item2 => item2.simple_call === item1.simple_call)
        );

        let rateList = [];
        let numList = [];

        this.frrTop20TopData.forEach(topItem => {
          let bottomItem = bottomDataList.find(item => item.simple_call === topItem.simple_call)

          if(bottomItem){
            rateList.push({simple_call:topItem.simple_call,rate:(topItem.num*this.rateNum/bottomItem.num).toFixed(this.fixNum)});
          }else{
            rateList.push({simple_call:topItem.simple_call,rate:0});
          }
          numList.push(topItem);
        });
        // 修改：计算有效数据的平均值
        // 过滤出有效的不良率数据（大于0的）
        const validRateItems = rateList.filter(item => parseFloat(item.rate) > 0);

        // 获取对应的退回数量和发货总数
        let totalReturnNum = 0;
        let totalShippedNum = 0;

        validRateItems.forEach(item => {
          const topItem = this.frrTop20TopData.find(t => t.simple_call === item.simple_call);
          const bottomItem = bottomDataList.find(b => b.simple_call === item.simple_call);

          if(topItem && bottomItem) {
            totalReturnNum += parseInt(topItem.num);
            totalShippedNum += parseInt(bottomItem.num);
          }
        });

        // 计算当月平均值（分子总和/分母总和）
        const monthAverage = totalShippedNum > 0 ? (totalReturnNum * this.rateNum / totalShippedNum).toFixed(this.fixNum) : 0;

        // 获取所有产品的总体平均不良率
        this.loadTotalAverage((totalAverage) => {
          // 2. 添加 isAboveAverage 字段并排序
          const processedData = rateList.map(item => {
            const rate = parseFloat(item.rate) || 0;
            return {
              ...item,
              isAboveAverage: rate > monthAverage  // 标记是否超出当月平均值
            };
          }).sort((a, b) => (parseFloat(b.rate) || 0) - (parseFloat(a.rate) || 0));  // 降序排序

          const aboveAverageMap = {};
          processedData.forEach(item => {
            aboveAverageMap[item.simple_call] = item.isAboveAverage;
          });

          let numNameList = [];
          let numDataList = [];
          // 按退回数量从大到小排序
          numList.sort((a, b) => parseInt(b.num) - parseInt(a.num));
          numList.forEach((item)=>{
            numNameList.push(item.simple_call);
            numDataList.push({value:item.num,itemStyle:{color:aboveAverageMap[item.simple_call] ? 'red':'#6A1B9A'}});
          })

          let rateNameList = [];
          let rateDataList = [];

          processedData.forEach((item)=>{
            rateNameList.push(item.simple_call);
            rateDataList.push({value:item.rate,itemStyle:{color:item.isAboveAverage ? 'red':'#6A1B9A'}});
          })

          //展示平均市场不良率TOP20
          this.loadFrrTop20Rate(rateNameList, rateDataList, monthAverage, totalAverage);
          this.loadFrrTop20Num(numNameList, numDataList);
          
          // 自动加载第一个柱子的饼图
          if(rateNameList.length > 0) {
            this.referred_simple_call = rateNameList[0];
            this.loadDefectData();
          }
        });
      },
      loadFrrTop20Rate(xList, dataList, monthAverage, totalAverage){
        let _this = this;
        this.chartFrrTop20RateTarget = this.frrTop20RateTarget || this.$echarts.init(this.$refs.frrTop20RateTarget)

        // 计算y轴最小值和最大值，保证平均线始终显示且视觉更美观
        let minAvg = Math.min(monthAverage, totalAverage);
        let maxAvg = Math.max(monthAverage, totalAverage);
        let minData = Math.min(...dataList.map(item => parseFloat(item.value)));
        let maxData = Math.max(...dataList.map(item => parseFloat(item.value)));
        let yMin = Math.min(minAvg, minData);
        yMin = yMin - Math.abs(yMin) * 0.1; // 比最小值低10%
        if (yMin > 0) yMin = Math.floor(yMin * 10000) / 10000; // 保留4位小数
        else yMin = 0;
        let yMax = Math.max(maxAvg, maxData);
        yMax = yMax + Math.abs(yMax) * 0.2; // 比最大值高20%
        yMax = Math.ceil(yMax * 10000) / 10000; // 保留4位小数

        let option={
          title: {
            text: '【'+this.lamp_type_show+'】'+(this.base ? '【'+this.base_show+'】' : '')+(this.mainPlantName ? '【'+this.mainPlantName+'】' : '')+'【'+this.currentMis+'】【'+this.clickMonth+'】平均市场不良率',
            left: '2%',
            textStyle: {
              fontSize: 16
            }
          },
          tooltip: {
            trigger: 'axis',
            axisPointer: {
              type: 'shadow'
            },
            formatter: function(params) {
              let str = params[0].name + '<br/>';
              params.forEach(item => {
                if(item.seriesName === '不良率' || item.seriesName === '当月平均线' || item.seriesName === '总体平均线') {
                  str += item.marker + item.seriesName + ': ' + item.value + _this.rateSymbol + '<br/>';
                }
              });
              return str;
            }
          },
          legend: {
            data: ['不良率', '当月平均线', '总体平均线'],
            right: '5%',
            top: '4%',
            selected: {
              '不良率': true,
              '当月平均线': true,
              '总体平均线': true
            }
          },
          grid: {
            left: '3%',
            right: '4%',
            bottom: '8%',
            containLabel: true
          },
          xAxis: {
            type: 'category',
            axisTick: {
              show: false
            },
            data: xList,
            axisLabel: {    //重点在这一块，其余可以忽略
              interval: 0,   //这个一定要有，别忘记了
              rotate: 12,
              textStyle: {
                fontSize: 12
              }
            },
          },
          yAxis: {
            type: 'value',
            name: this.rateName,
            min: yMin,
            max: yMax,
            axisLabel: {
              formatter: '{value}'+this.rateSymbol
            }
          },
          dataZoom: [
            {
              show: true,
              realtime: true,
              start: 0,
              end: xList.length > 10 ? (10 / xList.length) * 100 : 100, // 默认显示前10条
              height: 15,
              bottom: 0,
              backgroundColor: 'rgba(47, 69, 84, 0.15)',
              dataBackground: {
                lineStyle: {
                  opacity: 0.4
                },
                areaStyle: {
                  opacity: 0.15
                }
              },
              fillerColor: 'rgba(167,183,204,0.15)',
              borderColor: 'rgba(167,183,204,0.3)',
              handleIcon: 'path://M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
              handleSize: '70%',
              handleStyle: {
                color: '#fff',
                shadowBlur: 3,
                shadowColor: 'rgba(0, 0, 0, 0.3)',
                shadowOffsetX: 2,
                shadowOffsetY: 2
              },
              textStyle: {
                color: 'transparent'
              },
              z: 2
            },
            {
              type: 'inside',
              realtime: true,
              start: 0,
              end: xList.length > 10 ? (10 / xList.length) * 100 : 100, // 默认显示前10条
              zoomOnMouseWheel: true,
              moveOnMouseMove: true,
              xAxisIndex: [0]
            }
          ],
          series: [
            {
              data: dataList,
              type: 'bar',
              name:'不良率',
              barMaxWidth: 60,
              barMinWidth: 25,
              emphasis: {
                focus: 'series'
              },
              itemStyle: {
                normal: {
                  barBorderRadius: [3, 3, 3, 3],
                  label: {
                    show: true,
                    position:'top',
                    formatter: (params) => params.value + this.rateSymbol,
                    rotate: 0,
                    offset: [0, -5],
                    distance: 5
                  },
                }
              }
            },
            {
              name: '当月平均线',
              type: 'line',
              data: xList.map(() => monthAverage),
              symbol: 'none',
              color: '#1E88E5',
              lineStyle: {
                color: '#1E88E5',
                width: 3,
                type: 'solid'
              },
              label: {
                show: false
              },
              z: 10
            },
            {
              name: '总体平均线',
              type: 'line',
              data: xList.map(() => totalAverage),
              symbol: 'none',
              color: '#FFA000',
              lineStyle: {
                color: '#FFA000',
                width: 3,
                type: 'solid'
              },
              label: {
                show: false
              },
              z: 10
            }
          ]
        }
        option && this.chartFrrTop20RateTarget.setOption(option);
        this.chartFrrTop20RateTarget.off('click');
        this.chartFrrTop20RateTarget.on('click', function (params) {
          _this.referred_simple_call = params.name;
          _this.loadDefectData();
          console.log(params)
        });
      },
      loadDefectData(){
        let _this = this;
        if(!_this.referred_simple_call){
          return;
        }
        let params = {"SQL": this.pie_sql};
        app.utils.ajaxRequest({
          hideMsg: true,
          hideMask: true,
          url: app.path().dispose + "?functionCode=QMS_CUSTOM_QUERY_SQL",
          params: {
            "queryCondition[referred_simple_call]": _this.referred_simple_call,
            "queryCondition[base]": _this.base,
            "queryCondition[customer_id]": _this.mainPlantId,
            "queryCondition[month]": _this.clickMonth,
            "queryCondition[misStart]": _this.misQueryData[0],
            "queryCondition[misEnd]": _this.misQueryData[1],
            functionParam: JSON.stringify(params)
          },
          callBack(res) {
            if (res.success) {
              _this.loadDefectPieChart(res.rows);
            }
          }
        });
      },
      loadDefectPieChart(defectList){
        let _this = this;
        let subtext_num = 0;
        this.chartDefectLineTarget = this.defectLineTarget || this.$echarts.init(this.$refs.defectLineTarget)
        defectList.forEach((item)=>{
          subtext_num += item.value;
        })
        let option = {
          title: {
            text: '【'+this.referred_simple_call+'】'+(this.base ? '【'+this.base_show+'】' : '')+(this.mainPlantName ? '【'+this.mainPlantName+'】' : '')+'【'+this.currentMis+'】【'+this.clickMonth+'】缺陷分布',
            textStyle: {
              fontSize: 16
            },
            subtext:'总数：'+subtext_num,
            subtextStyle:{
              fontSize:14,
              align :'center'
            },
            left: '0',
            top: '5%'
          },
          tooltip: {
            trigger: 'item',
            formatter: '{a} <br/>{b} : {c} ({d}%)'
          },
          grid: {
            left: '1%',
            right: '1%',
            bottom: '1%',
            top:'1%',
            containLabel: true
          },
          series: [

            {
              name: '缺陷分布',
              top:'15%',
              type: 'pie',
              radius: ['25%', '65%'],
              center: ['50%', '55%'],
              //radius: '62%',
              avoidLabelOverlap: false,
              padAngle: 1,
              itemStyle: {
                borderRadius: 5,
                borderColor: '#fff',
                borderWidth: 2,
              },
              labelLine: {
                length:10,
                length2:10,
              },
              emphasis: {
                label: {
                  show: true,
                  fontSize: 16,
                  fontWeight: 'bold'
                }
              },
              label: {
                formatter: '{b}\n {@2012} ({d}%)',
                fontSize: 12
              },
              data: defectList
            }
          ]
        }
        option && this.chartDefectLineTarget.setOption(option);
      },
      loadFrrTop20Num(xList,dataList){
        this.chartFrrTop20NumTarget = this.frrTop20NumTarget || this.$echarts.init(this.$refs.frrTop20NumTarget)

        let option={
          title: {
            text: '【'+this.lamp_type_show+'】'+(this.base ? '【'+this.base_show+'】' : '')+(this.mainPlantName ? '【'+this.mainPlantName+'】' : '')+'【'+this.currentMis+'】【'+this.clickMonth+'】月退回件数量排布',
            left: '2%',
            textStyle: {
              fontSize: 16
            }
          },
          tooltip: {
            trigger: 'axis',
            axisPointer: {
              type: 'shadow'
            },
            formatter: function(params) {
              let str = params[0].name + '<br/>';
              params.forEach(item => {
                str += item.marker + item.seriesName + ': ' + item.value + '个<br/>';
              });
              return str;
            }
          },
          grid: {
            left: '3%',
            right: '1%',
            bottom: '8%',
            containLabel: true
          },
          xAxis: {
            type: 'category',
            axisTick: {
              show: false
            },
            data: xList,
            axisLabel: {
              interval: 0,
              rotate: 12,
              textStyle: {
                fontSize: 12
              },
              z: 10,
              margin: 10
            },
          },
          yAxis: {
            type: 'value',
            name: '退回数',
            axisLabel: {
              formatter: '{value}个'
            }
          },
          dataZoom: [
            {
              show: true,
              realtime: true,
              start: 0,
              end: xList.length > 10 ? (10 / xList.length) * 100 : 100, // 默认显示前10条
              height: 15,
              bottom: 0,
              backgroundColor: 'rgba(47, 69, 84, 0.15)',
              dataBackground: {
                lineStyle: {
                  opacity: 0.4
                },
                areaStyle: {
                  opacity: 0.15
                }
              },
              fillerColor: 'rgba(167,183,204,0.15)',
              borderColor: 'rgba(167,183,204,0.3)',
              handleIcon: 'path://M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
              handleSize: '70%',
              handleStyle: {
                color: '#fff',
                shadowBlur: 3,
                shadowColor: 'rgba(0, 0, 0, 0.3)',
                shadowOffsetX: 2,
                shadowOffsetY: 2
              },
              textStyle: {
                color: 'transparent'
              },
              z: 2
            },
            {
              type: 'inside',
              realtime: true,
              start: 0,
              end: xList.length > 10 ? (10 / xList.length) * 100 : 100, // 默认显示前10条
              zoomOnMouseWheel: true,
              moveOnMouseMove: true,
              xAxisIndex: [0]
            }
          ],
          series: [
            {
              data: dataList,
              type: 'bar',
              name:'退回数',
              barMaxWidth: 60,
              barMinWidth: 25,
              emphasis: {
                focus: 'series'
              },
              itemStyle: {
                normal: {
                  barBorderRadius: [3, 3, 3, 3],
                  label: {
                    show: true,
                    position:'top',
                    /*formatter: (params) => params.value + '‰'*/
                  },
                }
              },
            },
          ]
        }
        option && this.chartFrrTop20NumTarget.setOption(option);
      },
      // 导出Excel方法
      exportExcel() {
        try {
          console.log("开始导出Excel数据...");
          
          // 准备市场不良率数据 - 直接从图表获取
          let frrData = [];
          const monthList = this.month_list || [];
          console.log("月份列表:", monthList);

          // 从图表获取数据而不是重新计算
          if (this.chartFrrTarget) {
            const option = this.chartFrrTarget.getOption();
            if (option && option.series && option.xAxis && option.xAxis[0] && option.xAxis[0].data) {
              const months = option.xAxis[0].data;
              
              // 确保我们有所有的MIS系列
              let mis3Data = [], mis6Data = [], mis9Data = [], mis12Data = [], mis24Data = [], mis36Data = [];
              
              // 查找每个MIS系列数据
              option.series.forEach(series => {
                if (series.name === '3MIS') mis3Data = series.data;
                else if (series.name === '6MIS') mis6Data = series.data;
                else if (series.name === '9MIS') mis9Data = series.data;
                else if (series.name === '12MIS') mis12Data = series.data;
                else if (series.name === '24MIS') mis24Data = series.data;
                else if (series.name === '36MIS') mis36Data = series.data;
              });
              
              // 组合数据
              months.forEach((month, index) => {
                frrData.push({
                  month: month,
                  mis3: mis3Data[index] || "0",
                  mis6: mis6Data[index] || "0",
                  mis9: mis9Data[index] || "0",
                  mis12: mis12Data[index] || "0",
                  mis24: mis24Data[index] || "0",
                  mis36: mis36Data[index] || "0"
                });
              });
            } else {
              console.error("图表数据不完整，无法导出华视市场不良率总合");
            }
          } else {
            console.error("图表未初始化，无法导出华视市场不良率总合");
          }

          // 准备不良率TOP20数据 - 直接从图表获取
          let top20RateData = [];
          let monthAverage = 0;
          let totalAverage = 0;
          
          if (this.chartFrrTop20RateTarget) {
            const option = this.chartFrrTop20RateTarget.getOption();
            
            if (option && option.series && option.series.length >= 1 && option.xAxis && option.xAxis[0] && option.xAxis[0].data) {
              const simpleCallList = option.xAxis[0].data;
              const rateData = option.series[0].data; // 第一个系列是不良率
              
              // 获取平均线值
              if (option.series.length >= 3) {
                if (option.series[1] && option.series[1].data && option.series[1].data.length > 0) {
                  monthAverage = option.series[1].data[0];
                }
                if (option.series[2] && option.series[2].data && option.series[2].data.length > 0) {
                  totalAverage = option.series[2].data[0];
                }
              }
              
              // 从TOP20柱状图中获取数量数据
              let countData = [];
              if (this.chartFrrTop20NumTarget) {
                const numOption = this.chartFrrTop20NumTarget.getOption();
                if (numOption && numOption.series && numOption.series[0] && numOption.series[0].data) {
                  countData = numOption.series[0].data;
                }
              }
              
              // 组合数据
              simpleCallList.forEach((simple_call, index) => {
                const rateValue = typeof rateData[index] === 'object' ? rateData[index].value : rateData[index];
                const countValue = countData[index] ? (typeof countData[index] === 'object' ? countData[index].value : countData[index]) : 0;
                
                top20RateData.push({
                  simple_call: simple_call,
                  rate: rateValue || "0",
                  count: countValue || "0",
                  aboveTotal: parseFloat(rateValue || 0) > parseFloat(totalAverage || 0) ? '是' : '否'
                });
              });
            }
          }

          // 准备退回件数量排布数据 - 直接从图表获取
          let top20NumData = [];
          if (this.chartFrrTop20NumTarget) {
            const option = this.chartFrrTop20NumTarget.getOption();
            if (option && option.series && option.series[0] && option.xAxis && option.xAxis[0] && option.xAxis[0].data) {
              const simpleCallList = option.xAxis[0].data;
              const numData = option.series[0].data;
              
              simpleCallList.forEach((simple_call, index) => {
                const value = typeof numData[index] === 'object' ? numData[index].value : numData[index];
                top20NumData.push({
                  simple_call: simple_call,
                  count: value || "0"
                });
              });
            }
          }

          // 准备缺陷分布饼图数据 - 直接从图表获取
          let defectData = [];
          let defectTotal = 0;

          if (this.chartDefectLineTarget) {
            const option = this.chartDefectLineTarget.getOption();
            if (option && option.series && option.series[0] && option.series[0].data) {
              // 首先计算总数
              defectTotal = option.series[0].data.reduce((sum, item) => sum + (parseFloat(item.value) || 0), 0);
              
              // 然后创建数据数组
              defectData = option.series[0].data.map(item => {
                return {
                  name: item.name,
                  count: item.value,
                  percentage: ((item.value / defectTotal) * 100).toFixed(2) + '%'
                };
              });
            }
          }

          // 创建CSV内容
          let csvContent = '华视市场不良率总合\n月份,3MIS,6MIS,9MIS,12MIS,24MIS,36MIS\n';
          frrData.forEach(item => {
            // 确保月份保持YYYY-MM格式
            const monthValue = item.month; // 已经是YYYY-MM格式
            csvContent += `"${monthValue}",${item.mis3},${item.mis6},${item.mis9},${item.mis12},${item.mis24},${item.mis36}\n`;
          });

          // 添加平均市场不良率TOP20数据
          if (top20RateData.length > 0 && this.currentMis && this.clickMonth) {
            csvContent += `\n平均市场不良率TOP20 - ${this.currentMis} - ${this.clickMonth}\n`;
            // 确保显示正确的平均值（即使是0也要显示）
            csvContent += `当月平均不良率(${this.rateSymbol}): ${monthAverage || 0}, 总体平均不良率(${this.rateSymbol}): ${totalAverage || 0}\n`;
            csvContent += `产品简称,不良率(${this.rateSymbol}),退回数量,是否超过总体平均\n`;
            top20RateData.forEach(item => {
              csvContent += `${item.simple_call},${item.rate},${item.count},${item.aboveTotal}\n`;
            });
          }

          // 添加退回件数量排布数据
          if (top20NumData.length > 0 && this.currentMis && this.clickMonth) {
            csvContent += `\n退回件数量排布TOP20 - ${this.currentMis} - ${this.clickMonth}\n产品简称,退回数量\n`;
            top20NumData.forEach(item => {
              csvContent += `${item.simple_call},${item.count}\n`;
            });
          }

          // 添加缺陷分布饼图数据
          if (defectData.length > 0 && this.referred_simple_call && this.currentMis && this.clickMonth) {
            csvContent += `\n缺陷分布 - ${this.referred_simple_call} - ${this.currentMis} - ${this.clickMonth}\n缺陷名称,数量,百分比\n`;
            defectData.forEach(item => {
              csvContent += `${item.name},${item.count},${item.percentage}\n`;
            });
          }

          // 使用TextEncoder处理UTF-8编码
          const encoder = new TextEncoder();
          const data = encoder.encode('\ufeff' + csvContent);
          const blob = new Blob([data], { type: 'text/csv;charset=utf-8' });

          // 创建下载链接
          const link = document.createElement('a');
          link.href = URL.createObjectURL(blob);
          link.download = '产品售后市场表现.csv';
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
          URL.revokeObjectURL(link.href);

          console.log("Excel导出完成，数据行数:", frrData.length);
          // 安全地使用app.$message
          if (window.app && app.$message && typeof app.$message.success === 'function') {
            app.$message.success('导出Excel成功');
          } else {
            console.log('导出Excel成功');
          }
        } catch (error) {
          console.error('导出Excel失败:', error);
          // 安全地使用app.$message
          if (window.app && app.$message && typeof app.$message.error === 'function') {
            app.$message.error('导出Excel失败');
          } else {
            console.error('导出Excel失败');
          }
        }
      },

      // 导出图表图片
      exportChart() {
        try {
          // 导出华视市场不良率总合图表
          if (this.chartFrrTarget) {
            let frrBase64 = this.chartFrrTarget.getDataURL({
              type: 'png',
              pixelRatio: 2,
              backgroundColor: '#ffffff'
            });
            let frrLink = document.createElement('a');
            frrLink.download = '华视市场不良率总合.png';
            frrLink.href = frrBase64;
            frrLink.click();
          }

          // 导出平均市场不良率TOP20图表
          if (this.chartFrrTop20RateTarget) {
            let top20RateBase64 = this.chartFrrTop20RateTarget.getDataURL({
              type: 'png',
              pixelRatio: 2,
              backgroundColor: '#ffffff'
            });
            let top20RateLink = document.createElement('a');
            top20RateLink.download = '平均市场不良率TOP20.png';
            top20RateLink.href = top20RateBase64;
            top20RateLink.click();
          }

          // 导出退回件数量排布TOP20图表
          if (this.chartFrrTop20NumTarget) {
            let top20NumBase64 = this.chartFrrTop20NumTarget.getDataURL({
              type: 'png',
              pixelRatio: 2,
              backgroundColor: '#ffffff'
            });
            let top20NumLink = document.createElement('a');
            top20NumLink.download = '退回件数量排布TOP20.png';
            top20NumLink.href = top20NumBase64;
            top20NumLink.click();
          }

          // 导出缺陷分布饼图
          if (this.chartDefectLineTarget) {
            let defectBase64 = this.chartDefectLineTarget.getDataURL({
              type: 'png',
              pixelRatio: 2,
              backgroundColor: '#ffffff'
            });
            let defectLink = document.createElement('a');
            defectLink.download = '缺陷分布.png';
            defectLink.href = defectBase64;
            defectLink.click();
          }

          // 安全地使用app.$message
          if (window.app && app.$message && typeof app.$message.success === 'function') {
            app.$message.success('导出图表成功');
          } else {
            console.log('导出图表成功');
          }
        } catch (error) {
          console.error('导出图表失败:', error);
          // 安全地使用app.$message
          if (window.app && app.$message && typeof app.$message.error === 'function') {
            app.$message.error('导出图表失败');
          } else {
            console.error('导出图表失败');
          }
        }
      },
    },
    mounted () {
      this.loadTypes();
      this.loadBases();
      this.loadMainPlant();
      this.loadFrrData();
      window.onresize=()=>{
        this.chartFrrTarget && this.chartFrrTarget.resize();
        this.chartFrrTop20RateTarget && this.chartFrrTop20RateTarget.resize();
        this.chartFrrTop20NumTarget && this.chartFrrTop20NumTarget.resize();
        this.chartDefectLineTarget && this.chartDefectLineTarget.resize();
      }
    },
    props: {
      prop:{type:String,desc:'基本参数'}
    }
  }
</script>
  